package com.example.vv.model.search;

import android.Manifest;
import android.app.Dialog;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Paint;
import android.graphics.drawable.AnimationDrawable;
import android.os.Handler;
import android.os.Message;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.baidu.aip.asrwakeup3.core.mini.AutoCheck;
import com.baidu.speech.EventListener;
import com.baidu.speech.EventManager;
import com.baidu.speech.EventManagerFactory;
import com.baidu.speech.asr.SpeechConstant;
import com.example.vv.R;
import com.example.vv.fragmentWork.Sqlite.SqlHelper;
import com.example.vv.adapter.BaseRecyclerViewAdapter;
import com.example.vv.fragmentWork.entity.HotEntity;
import com.example.vv.fragmentWork.entity.SearchEntity;
import com.example.vv.fragmentWork.mvp.MvpActivity;
import com.example.vv.fragmentWork.utlis.LogUtils;
import com.example.vv.model.search.contract.SearchContract;
import com.example.vv.model.search.presenter.SearchPresenter;
import com.example.vv.model.searchDetail.SIDActivity;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import org.greenrobot.eventbus.EventBus;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import butterknife.BindView;

/**
 * 尚未完成将搜索历史写入数据库中 未接受到任何语音时的判断
 */
public class SearchActivity extends MvpActivity<SearchContract.View, SearchPresenter> implements SearchContract.View, EventListener {

    @BindView(R.id.back)
    ImageView back;
    @BindView(R.id.et_search)
    EditText etSearch;
    @BindView(R.id.search)
    TextView search;
    @BindView(R.id.search_recycle)
    RecyclerView searchRecycle;
    @BindView(R.id.search_recycle2)
    RecyclerView searchRecycle2;
    @BindView(R.id.ll1)
    LinearLayout ll1;
    @BindView(R.id.search_recycle3)
    RecyclerView searchRecycle3;
    @BindView(R.id.ll2)
    LinearLayout ll2;
    @BindView(R.id.img_voice)
    ImageView imgVoice;
    @BindView(R.id.tv_clear)
    TextView tvClear;
    List<String> list;
    @BindView(R.id.img_delete)
    ImageView imgDelete;
    private EventManager asr;
    protected boolean enableOffline = false; // 测试离线命令词，需要改成true
    Dialog dialog;
    AnimationDrawable background;
    ContentValues cv;
    SQLiteDatabase sqLiteDatabase;
    List<String> dataBaseData = new ArrayList<>();
    SqlHelper sqlHelper;

    @Override
    public int initLayout() {
        return R.layout.activity_search;
    }

    @Override
    public SearchPresenter initPresenter() {
        return new SearchPresenter();
    }

    @Override
    public void initView() {
        sqlHelper = new SqlHelper(this, "History.db", null, 1);
        initDB();
        intiDialog();
        etSearch.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                isEmpty();
            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                isEmpty();
                presenter.setSearchData(charSequence.toString() + "");
            }

            @Override
            public void afterTextChanged(Editable editable) {
                isEmpty();
                presenter.setHistoryData(editable.toString());
            }
        });
        imgVoice.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                background.start();
                dialog.show();
                initVoice();
            }
        });
        back.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                finish();
            }
        });
    }

    private void initDB() {
        sqLiteDatabase = sqlHelper.getWritableDatabase();
        dataBaseData = getDataBaseData(sqLiteDatabase);
        if (dataBaseData.size() != 0) {
            presenter.setHistoryData2(dataBaseData);
        }
    }

    List<String> list2 = new ArrayList<>();
    private List<String> getDataBaseData(SQLiteDatabase sqLiteDatabase) {
        String sql = "select * from history";
        Cursor cursor = sqLiteDatabase.rawQuery(sql, null);
        while (cursor.moveToNext()) {
            if (cursor.moveToLast()) {
                String history = cursor.getString(cursor.getColumnIndex("history"));
                if (history.equals("null")) {
                }else {
                    list2 = StringToList(history);
                }
            }
        }
        cursor.close();
        return list2;
    }

    private void intiDialog() {
        dialog = new Dialog(this, R.style.dialog);
        dialog.getWindow().setDimAmount(0);
        View view = LayoutInflater.from(this).inflate(R.layout.voice_dialog, null);
        background = (AnimationDrawable) view.findViewById(R.id.voice_dialog_img).getBackground();
        dialog.setContentView(view);
    }

    /**
     * 清空搜索历史
     */
    private void intiClear() {
        if (list.size() == 0) {
            tvClear.setVisibility(View.GONE);
        } else {
            tvClear.setVisibility(View.VISIBLE);
            tvClear.setOnClickListener(view -> {
                presenter.removeAll();
                String sql = "delete from history";
                sqLiteDatabase.execSQL(sql);
                getHistoryData(list);
            });
        }
    }

    /**
     * 点击删除按钮清除输入框
     */
    private void initClear2() {
        imgDelete.setOnClickListener(view -> {
            etSearch.setText("");
        });
    }

    public void isEmpty() {
        if (TextUtils.isEmpty(etSearch.getText())) {
            ll1.setVisibility(View.VISIBLE);
            ll2.setVisibility(View.GONE);
            imgDelete.setVisibility(View.GONE);
            imgVoice.setVisibility(View.VISIBLE);
        } else {
            ll2.setVisibility(View.VISIBLE);
            ll1.setVisibility(View.GONE);
            imgDelete.setVisibility(View.VISIBLE);
            imgVoice.setVisibility(View.GONE);
            initClear2();
        }
    }

    /**
     * 录音事件
     */
    private void initVoice() {
        initPermission();
        onStartVoice();
    }


    @Override
    public void initData() {
        presenter.setHotData();
    }

    @Override
    public void doBusiness() {

    }

    @Override
    public View titleView() {
        return null;
    }


    @Override
    public Context getMContext() {
        return this;
    }

    /**
     * 搜索的结果返回
     *
     * @param searchEntity
     */
    @Override
    public void getSearchData(SearchEntity searchEntity) {
        LogUtils.Log(searchEntity.getCurPage() + "searchdata--111");
        BaseRecyclerViewAdapter adapter = presenter.setSearchAdapter(searchEntity.getDatas(), this);
        searchRecycle3.setAdapter(adapter);
        adapter.setOnItemClickListener(new BaseRecyclerViewAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(RecyclerView.Adapter adapter, View v, int position) {
                startActivity(new Intent(SearchActivity.this, SIDActivity.class));
                EventBus.getDefault().postSticky(searchEntity.getDatas().get(position));
            }
        });
    }

    /**
     * 获取热搜
     *
     * @param hotEntity
     */
    @Override
    public void getHotData(List<HotEntity> hotEntity) {
        LogUtils.Log(hotEntity.toString() + "11111");
        BaseRecyclerViewAdapter adapter = presenter.setHOtAdapter(hotEntity, this);
        searchRecycle2.setAdapter(adapter);
        adapter.setOnItemClickListener((adapter1, v, position) -> {
            String name = hotEntity.get(position).getName();
            etSearch.setText(name);
            //搜索请求
            presenter.setSearchData(name);
            //添加搜索历史
//            presenter.setHistoryData(name);
        });
    }

    /**
     * 获取搜索历史数据 初始化历史记录
     * @param history
     */
    @Override
    public void getHistoryData(List<String> history) {
        list = history;
        intiClear();
        intiRecycle(history);
        BaseRecyclerViewAdapter adapter = presenter.setHistoryAdapter(history, this);
        searchRecycle.setAdapter(adapter);
    }

    private Paint mSearchHistoryPaint;
    private int mPaddingSize;

    private void intiRecycle(List<String> history) {
        searchRecycle.setHasFixedSize(true);
        mSearchHistoryPaint = new Paint();//画笔用来计算文字的宽度
        //设置文字的大小，注意布局文件里写的是sp，这里需要进行转换成对应的px，我这里就不写了
        mSearchHistoryPaint.setTextSize(60);
        //textview的大小，包括文字大小和左右内边距，所以这个值表示内边距大小，同样注意转换
        mPaddingSize = 60;
        //获取屏幕的宽度，我这里rccyclerview正好是屏幕的宽度，否则应替换为rec的宽度
        final int width = getWindowManager().getDefaultDisplay().getWidth();
        //这里讲网格的数量设置为屏幕的宽度，网格无限小
        GridLayoutManager gridLayoutManager = new GridLayoutManager(this, width);
        //设置每个文字占据的网格数
        gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                //就是这里 需要测量文字的宽度，加上左右内边距
                int textWidth = (int) mSearchHistoryPaint.measureText(history.get(position)) + mPaddingSize;
                //如果文字的宽度超过屏幕的宽度，那么我们就设置为屏幕宽度
                return textWidth > width ? width : textWidth;
            }
        });
        searchRecycle.setLayoutManager(gridLayoutManager);
    }

    /**
     * enableOffline设为true时，在onCreate中调用
     * 基于SDK离线命令词1.4 加载离线资源(离线时使用)
     */
    private void loadOfflineEngine() {
        Map<String, Object> s1 = new LinkedHashMap<String, Object>();
        s1.put(SpeechConstant.DECODER, 2);
        s1.put(SpeechConstant.ASR_OFFLINE_ENGINE_GRAMMER_FILE_PATH, "assets://baidu_speech_grammar.bsg");
        asr.send(SpeechConstant.ASR_KWS_LOAD_ENGINE, new JSONObject(s1).toString(), null, 0, 0);
    }

    /**
     * 获取权限
     */
    private void initPermission() {
        // 基于sdk集成1.1 初始化EventManager对象
        asr = EventManagerFactory.create(this, "asr");
        // 基于sdk集成1.3 注册输出事件类
        asr.registerListener(this); //  EventListener 中 onEvent方法

        if (enableOffline) {
            loadOfflineEngine(); // 测试离线命令词请开启, 测试 ASR_OFFLINE_ENGINE_GRAMMER_FILE_PATH 参数时开启
        }

        String[] permissions = {
                Manifest.permission.RECORD_AUDIO,
                Manifest.permission.ACCESS_NETWORK_STATE,
                Manifest.permission.INTERNET,
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
        };
        ArrayList<String> applyLists = new ArrayList<>();
        for (String permission : permissions) {
            if (PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(this, permission)) {
                applyLists.add(permission);
                //进入这里代表没有权限
            }
        }
        String tmpList[] = new String[applyLists.size()];
        if (!applyLists.isEmpty()) {
            //请求权限
            ActivityCompat.requestPermissions(this, applyLists.toArray(tmpList), 123);
        }

    }

    /**
     * 点击录音按钮开始录音
     */
    public void onStartVoice() {
        if (TextUtils.isEmpty(etSearch.getText())) {
            etSearch.setText("");
        }
        Map<String, Object> s1 = new LinkedHashMap<String, Object>();
        String event = null;
        event = SpeechConstant.ASR_START; // 开始录音

        if (enableOffline) {
            s1.put(SpeechConstant.DECODER, 2); //离在线的并行策略
        }
        // 基于SDK集成2.1 设置识别参数
        s1.put(SpeechConstant.ACCEPT_AUDIO_VOLUME, false);

        (new AutoCheck(this, new Handler() {
            public void handleMessage(Message msg) {
                if (msg.what == 100) {
                    AutoCheck autoCheck = (AutoCheck) msg.obj;
                    synchronized (autoCheck) {
                        String message = autoCheck.obtainErrorMessage(); // autoCheck.obtainAllMessage();
                        Log.w("AutoCheckMessage", message); //log中查看代码
                    }

                }
            }
        }, enableOffline)).checkAsr(s1);
        String json = null;
        json = new JSONObject(s1).toString();
        asr.send(event, json, null, 0, 0);
    }

    /**
     * 停止录音
     */
    public void onStopVoice() {
        asr.send(SpeechConstant.ASR_STOP, null, null, 0, 0);
        background.stop();
        dialog.cancel();
    }

    /**
     * 语音的结果回调
     *
     * @param s
     * @param s1
     * @param bytes
     * @param i
     * @param i1
     */
    @Override
    public void onEvent(String s, String s1, byte[] bytes, int i, int i1) {

        String result = "";
        if (s.equals(SpeechConstant.CALLBACK_EVENT_ASR_PARTIAL)) {
            // 识别相关的结果都在这里
            if (s1.contains("\"error\"")) {
                onStopVoice();
            }
            if (s1.contains("\"final_result\"")) {
                try {
                    JSONObject jsonObject = new JSONObject(s1);
                    result = jsonObject.getString("best_result");
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }
        printLog(result);
    }

    /**
     * 输出语音识别结果
     *
     * @param text
     */
    private void printLog(String text) {
        Log.i(getClass().getName(), text + "");
        if (TextUtils.isEmpty(etSearch.getText())) {
            etSearch.setText(text);
        } else {
            etSearch.append(text);
            onStopVoice();
        }
    }


    /**
     * 返回按钮
     * 当输入框有字时 点击后回到原始界面
     * 原始界面再点击回到主界面
     */
    @Override
    public void onBackPressed() {
        if (!TextUtils.isEmpty(etSearch.getText())) {
            ll1.setVisibility(View.VISIBLE);
            ll2.setVisibility(View.GONE);
            imgDelete.setVisibility(View.GONE);
            imgVoice.setVisibility(View.VISIBLE);
            etSearch.setText("");
        } else {
            /**
             * 将list转化成string
             */
            String str = ListToString();
            cv = new ContentValues();
            cv.put("history", str);
            sqLiteDatabase.insert("history", null, cv);
            LogUtils.Log("插入数据");
            sqLiteDatabase.close();
//            sqlHelper.close();
            super.onBackPressed();
        }
        return;
    }

    private String ListToString() {
        String s = new Gson().toJson(list);
        return s;
    }

    private List<String> StringToList(String s) {
        List<String> o = new Gson().fromJson(s, new TypeToken<List<String>>() {
        }.getType());
        return o;
    }

    @Override
    protected void onDestroy() {
        if (asr != null) {
            asr.unregisterListener(this);
        }
        super.onDestroy();
    }
}